package com.cxy.common.boot;

import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.util.CollectionUtils;


import java.security.CodeSource;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

/*********************************************************
 * 文件名称：CxyCloudBootstrap.java
 * 系统名称：CXY自定义系统
 * 模块名称：com.cxy.common.boot
 * 功能说明：启动器
 * 开发人员 @author：caoxy31978
 * 开发时间 @date：2023/6/28 9:53
 * 修改记录：程序版本  修改日期  修改人员  修改单号  修改说明
 *********************************************************/
public class CxyCloudBootstrap {

    private static final String SPLIT = "-";
    private static final String CONFIG_LOCATION_KEY = "--spring.config.additional-location=";
    private static final String JAR_APPENDIX = ".jar";
    private static final String ARK_APPENDIX = "!/";
    private static final String SPRING_BOOT_CLASSES_APPENDIX = "!/BOOT-INF/classes";
    private static final String EQ_SIGN = "=";
    private static final String ARK_BIZ_APPENDIX = "ark-biz";

    public static Boolean isArkEnable() {
        try {
            String enable = System.getProperty(CxyCloudConstants.ARK_ENABLE, Boolean.FALSE.toString());
            return Boolean.TRUE.toString().equalsIgnoreCase(enable);
        } catch (Exception e) {
            return false;
        }
    }

    public static String[] prepare(String[] args, Object source, SpringApplication application) {
        if (isArkEnable()) {
            String artifactId = getArtifactId(source, application);
            if (StringUtils.isNotBlank(artifactId)) {
                List<String> argList = new LinkedList();
                args = null == args ? new String[0] : args;
                Collections.addAll(argList, args);
                argList.add(CONFIG_LOCATION_KEY + artifactId + "/");
                return (String[])argList.toArray(new String[argList.size()]);
            }
        }

        if (args != null && args.length > 0) {
            String[] sps = args[0].split(EQ_SIGN);
            return sps.length > 1 && CxyCloudConstants.CXYFILE.equals(sps[0]) ? new String[]{CONFIG_LOCATION_KEY + sps[1]} : args;
        } else {
            return args;
        }
    }

    protected static String getArtifactId(Object source, SpringApplication application) {
        try {
            CodeSource codeSource = null;
            if (null != source) {
                codeSource = ((Class)source).getProtectionDomain().getCodeSource();
            }

            if (null == codeSource && null != application) {
                Set<Object> sources = application.getAllSources();
                if (CollectionUtils.isEmpty(sources)) {
                    return null;
                }
                for (Object sourceClass : sources) {
                    try {
                        if (null != sourceClass) {
                            codeSource = ((Class)sourceClass).getProtectionDomain().getCodeSource();
                            break;
                        }
                    } catch (Exception e) {
                    }
                }
            }

            if (null == codeSource || codeSource.getLocation() == null) {
                return null;
            }
            String file = codeSource.getLocation().getFile();
            if (StringUtils.isEmpty(file)) {
                return null;
            }
            String fileWithVersion = "";
            String version = "";
            file = file.endsWith(ARK_APPENDIX) ? file.substring(0, file.length() - ARK_APPENDIX.length()) : file;
            file = file.endsWith(SPRING_BOOT_CLASSES_APPENDIX) ? file.substring(0, file.length() - SPRING_BOOT_CLASSES_APPENDIX.length()) : file;
            if (file.endsWith(JAR_APPENDIX)) {
                file = file.substring(0, file.length() - JAR_APPENDIX.length());
                int i = file.lastIndexOf("/");
                file = i >= 0 ? file.substring(i + 1) : file;
                fileWithVersion = file;
                i = file.indexOf(SPLIT);

                for(file = i >= 0 ? file.substring(i + 1) : file; file.length() > 0 && !Character.isDigit(file.charAt(0)); file = file.substring(i + 1)) {
                    i = file.indexOf(SPLIT);
                    if (i < 0) {
                        break;
                    }
                }

                if (!Character.isDigit(file.charAt(0))) {
                    version = "";
                } else {
                    version = file;
                }
            }

            if (StringUtils.isEmpty(fileWithVersion)) {
                return null;
            } else {
                String fileWithOutVersion = StringUtils.isEmpty(version) ? fileWithVersion : fileWithVersion.replace(version, "");

                for(fileWithOutVersion = fileWithOutVersion.endsWith(ARK_BIZ_APPENDIX) ? fileWithOutVersion.substring(0, fileWithOutVersion.length() - ARK_BIZ_APPENDIX.length()) : fileWithOutVersion; fileWithOutVersion.endsWith(SPLIT); fileWithOutVersion = fileWithOutVersion.substring(0, fileWithOutVersion.length() - SPLIT.length())) {
                }
                return fileWithOutVersion;
            }
        } catch (Exception e) {
            return null;
        }
    }

    public static ConfigurableApplicationContext run(SpringApplication application) {
        return run(application, null, null);
    }

    public static ConfigurableApplicationContext run(Class<?> source, String[] args) {
        return run(null, source, args);
    }

    public static ConfigurableApplicationContext run(SpringApplication application, Class<?> source, String[] args) {
        String[] newArgs = prepare(args, source, application);
        newArgs = newArgs == null ? new String[0] : newArgs;
        application = application == null ? new SpringApplication(source) : application;
        return application.run(newArgs);
    }
}
